#!/usr/bin/env node

var cp = require('child_process')
var path = require('path')
var packageCfg = require('../package.json')
var installCfg = require('./config')
var PackageDb = require('./db')
var db = new PackageDb(installCfg.dbfile).load()

const NPM_I_INIT = process.env.NPM_I_INIT === '1' ? true : false
const NPM_I_RELEASE = process.env.NPM_I_RELEASE === '1' ? true : false

function contains(names, name) {
  for (var n of names) {
    if (n === name) {
      return true
    }
  }
  return false
}

function installDependencies() {
  if (packageCfg.dependencies) {
    for (var name in packageCfg.dependencies) {
      if (!db.contains(name, packageCfg.dependencies[name]) && !contains(installCfg.natives, name)) {
        cp.spawnSync('npm', [
          'install', '--verbose', name + '@' + packageCfg.dependencies[name]
        ], { 
          cwd: installCfg.appHome, 
          stdio: 'inherit' 
        })
        db.add(name, packageCfg.dependencies[name]).dump()
      }
    }
  }
}

function installDevDependencies() {
  if (packageCfg.devDependencies) {
    for (var name in packageCfg.devDependencies) {
      if (!db.contains(name, packageCfg.devDependencies[name]) && !contains(installCfg.natives, name)) {
        cp.spawnSync('npm', [
          'install', 
          '--verbose', 
          name + '@' + packageCfg.devDependencies[name]
        ], { 
          cwd: installCfg.appHome, 
          stdio: 'inherit'
        })
        if (name === 'vscode') {
          var env = Object.create(null)
          Object.assign(env, process.env)
          env.npm_package_engines_vscode = packageCfg.devDependencies[name]
          cp.spawnSync('node', [
            path.join(installCfg.appHome, 'node_modules/vscode/bin/install') 
          ], { 
            cwd: installCfg.appHome, 
            stdio: 'inherit', 
            env: env 
          })
        }
        db.add(name, packageCfg.devDependencies[name]).dump()
      }
    }
  }
}

function installNativeSqlite() {
  if (!db.contains('sqlite3', packageCfg.dependencies['sqlite3']) && contains(Object.keys(packageCfg.dependencies)), 'sqlite3') {
    cp.spawnSync('npm', [
      'install', '--verbose', '--build-from-source', '--sqlite=' + installCfg.sqlite.lib, 'sqlite3'
    ], { 
      cwd: installCfg.appHome,
      stdio: 'inherit' 
    })
    var env = Object.create(null)
    Object.assign(env, process.env)
    // 注意：node-gyp 编译 sqlite3 的时候，需要检验 iojs-{ELECTRON_VERSION} 已经存在。
    // 如果没有，会自动下载。如果网络不好，这会花费很长时间。请把
    // https://atom.io/download/electron/v{ELECTRON_VERSION}/iojs-v{ELECTRON_VERSION}.tar.gz
    // 的 release 版本下载，并且复制到 {env.HOME}/.node-gyp/ 目录，这样可以跳过下载。
    env.HOME = installCfg.electron.gypHome
    cp.spawnSync('node-gyp', [
      'rebuild', 
      '--verbose', 
      '--target=' + installCfg.electron.version, 
      '--arch=' + installCfg.electron.arch,
      '--dist-url=' + installCfg.electron.distUrl, 
      '--module_name=' + installCfg.sqlite.moduleName, 
      '--module_path=' + installCfg.sqlite.modulePath
    ], { 
      cwd: path.join(installCfg.appHome, 'node_modules/sqlite3'), 
      stdio: 'inherit', 
      env: env
    })
    db.add('sqlite3', packageCfg.dependencies['sqlite3']).dump()
  }
}

function clean() {
  cp.spawnSync('rm', [
    '-r', 
    '-f',
    path.join(installCfg.appHome, 'node_modules')
  ], { 
    cwd: installCfg.appHome,
    stdio: 'inherit' 
  })
  cp.spawnSync('mkdir', [
    '-p', 
    path.join(installCfg.appHome, 'node_modules')
  ], { 
    cwd: installCfg.appHome,
    stdio: 'inherit' 
  })
  db.clean()
}

function main() {
  if (NPM_I_INIT) {
    clean()
  }
  if (!NPM_I_RELEASE) {
    installDevDependencies()
  }
  installDependencies()
  if (installCfg.sqlite) {
    installNativeSqlite()
  }
}

main()